#ifndef _DATABASE_H
#define _DATABASE_H

class DLL_EXPORT QField
{
	friend class QRow;
	char* field;
	QField(char* f) : field(f)
	{
	}
public:
	operator ui32()
	{
		if(field)
			return atoi(field);
		else return 0;
	}

	operator ui16()
	{
		if(field)
			return atoi(field);
		else return 0;
	}

	operator ui8()
	{
		if(field)
			return atoi(field);
		else return 0;
	}

	operator char*()
	{
		return field;
	}

	operator float()
	{
		return (float)atof(field);
	}

	operator ui64()
	{
		ui64 out;
		sscanf(field, "%llu", &out);
		return out;
	}

	char* GetChar()
	{
		return field;
	}

	ui32 GetUI32()
	{
		return atoi(field);
	}
};

class DLL_EXPORT QRow
{
	friend class Database;
	friend class QResult;
	MYSQL_ROW& currow;
	QRow(MYSQL_ROW& rw) : currow(rw)
	{
	}
public:
	QField& operator[] (ui8 index)
	{
		QField* q = new QField(currow[index]);
		return (*q);
	}
};

class DLL_EXPORT QResult
{
	friend class Database;
	MYSQL_RES* m_result;
	MYSQL_ROW currow;
	QResult(MYSQL_RES* r) : m_result(r)
	{
		currow = mysql_fetch_row(m_result);
	}
public:
	static void operator delete(void* pMem)
	{
		if(((QResult*)pMem)->m_result)
			mysql_free_result(((QResult*)pMem)->m_result);
		delete [] pMem;
	}

	QRow& Fetch()
	{
		QRow* row = new QRow(currow);
		return (*row);
	}

	bool NextRow()
	{
		currow = mysql_fetch_row(m_result);
		if(currow)
			return true;
		else
			return false;
	}

	int NumRows()
	{
		return (int)mysql_num_rows(m_result);
	}

	int NumFields()
	{
		return (int)mysql_num_fields(m_result);
	}
};

class DLL_EXPORT Database
{
	MYSQL* m_connection;
	MYSQL_RES* m_result;
public:
	Database()
	{
		m_connection = mysql_init(NULL);
	}

	void Connect(const char* host, const char* user, const char* pw, const char* db, ui32 port);

	void Query(const char*, ...);
	QResult* SafeQuery(const char*, ...);

};

#endif